import chartFactory from '../index.js';

import bus from '../../bus';

const chart = {};


bus.$on('activate', (data) => {
  chart.highlight(data)
})
bus.$on('deactivate', (data) => {
  chart.highlight(data, false);
})

chart.highlight = function (data, flag = true) {
  if (this.container == null)
    return;
  let result = this.container.selectAll('rect').filter(d => d.data.name === data.name);
  if (flag) {
    result.attr('stroke', '#000');
  } else {
    result.attr('stroke', 'transparent');
  }

}

chart.create = chartFactory;

chart.init = function (opt) {
  this.create(opt);


  this.color = d3.scaleOrdinal().domain([0, 1, 2, 3]).range(['#006266', '#1289A7', '#12CBC4', '#C4E538'])



  // this.color = ['#8c510a', '#d8b365', '#f6e8c3', '#f5f5f5', '#c7eae5', '#5ab4ac', '#01665e'];

  this.tooltip = d3.select(this.config.target + ` .tooltip`);

  let parent = document.querySelector(this.config.target);
  this.width = parent.clientWidth - this.config.margin.left - this.config.margin.right;
  this.height = parent.clientHeight - this.config.margin.top - this.config.margin.bottom;
  this.stratify = d3.stratify().id(d => d.name).parentId(d => d.parent);
  this.treemap = d3.treemap().size([this.width, this.height])
    .paddingOuter(3)
    .paddingTop(19)
    .paddingInner(1)
    .round(true);
}

chart.update = function (architecture, industries) {


  function hovered (hover) {
    return function (d) {
      if (d.ancestors() == null)
        return;
      d3.selectAll(d.ancestors().map(function (d) { return d.node; }))
        .classed("node--hover", hover)
        .select("rect")
        .attr("width", function (d) { return d.x1 - d.x0 - hover; })
        .attr("height", function (d) { return d.y1 - d.y0 - hover; });
    };
  }

  // 树图每一次更新时，接收两部分数据
  // 一是定向体系数据
  // 二是所选择的行业数据



  this.architecture = architecture || this.architecture;
  this.industries = industries || this.industries;

  if (this.architecture == null || this.industries == null)
    return

  let treemapData = this.process(this.architecture, this.industries);

  let update = this.container.selectAll('.node').data(treemapData.descendants()),
    enter = update.enter(), exit = update.exit();
  exit.remove();
  let cell = enter.append('g').attr('class', 'node').merge(update).attr('transform', d => `translate(${d.x0}, ${d.y0})`)
    .each(function (d) {
      d.node = this;
    }).on('mouseover', hovered(true)).on('mouseout', hovered(false));

  cell.append('rect').attr('id', d => d.data.name)
    .attr('width', d => d.x1 - d.x0)
    .attr('height', d => d.y1 - d.y0)
    .attr('fill', d => {
      return this.color(d.depth)
    });

  let label = cell.append("text")
    .attr("clip-path", function (d) { return "url(#clip-" + d.id + ")"; });

  label.filter(d => d.children).selectAll('tspan').data(d => [d.id])
    .enter().append('tspan')
    .attr('x', (d, i) => i ? null : 4)
    .attr('y', 13)
    .text(d => d);

  label
    .filter(function (d) { return !d.children; })
    .selectAll("tspan")
    .data(d => [d.id])
    .enter().append("tspan")
    .attr("x", 4)
    .attr("y", function (d, i) { return 13 + i * 10; })
    .text(function (d) { return d; });

  cell.on('mouseenter', (d) => {
    this.tooltip.style('visibility', 'visible');
    let tooptipStr = `定向名称: ${d.data.name}<br/>` + `
    ${d.data.industries.map(item => `${item.industry}: ${item.value}`).join(`<br/>`)}`

    this.tooltip.html(tooptipStr);
    this.tooltip.width = Number.parseInt(this.tooltip.style('width').replace('px', ''));
    this.tooltip.height = Number.parseInt(this.tooltip.style('height').replace('px', ''));
  }).on('mouseleave', () => {
    this.tooltip.style('visibility', 'hidden');
  }).on('mousemove', (d) => {
    if (d3.event.pageX + 30 + this.tooltip.width > window.innerWidth) {
      this.tooltip.style('left', d3.event.pageX - 20 - this.tooltip.width + 'px');
    } else {
      this.tooltip.style('left', d3.event.pageX + 20 + 'px');
    }
    if (d3.event.pageY + 30 + this.tooltip.height > window.innerHeight) {
      this.tooltip.style('top', d3.event.pageY - 20 - this.tooltip.height + 'px');
    }
    else {
      this.tooltip.style('top', d3.event.pageY + 20 + 'px');
    }
  })
}

chart.process = function (architecture, industries) {

  // 由于不知名原因，在此采用复制定向树的方式装载数据
  // 其中会使用到d3.stratify
  // 首先需要从上到下，以层次遍历方式遍历节点
  // 此时architecture为保存定向体系树的数组，可依据此数据进行深拷贝

  let result = [];

  for (let node of architecture) {
    // 逐个遍历节点，并装载数据

    if (node.name === '根定向') {
      result.push(Object.assign({}, node));
      continue;
    }

    // 但为了配合定向体系展示，需要对数据进行修改

    // 可能选择了多个行业，因此需要使用数组保存
    let sum = [];
    industries.forEach(industry => {
      let nodeData = industry.data.find(item => item.name === node.name)
      sum.push(Object.assign({}, { industry: industry.name, value: nodeData ? nodeData.value : 0 }))
    })
    // 自此开始进行深拷贝
    // 但仍要进行判断，考虑到d3的特殊性，需要加入一个虚拟叶子节点

    // sum中保存的是某一节点在所选行业上的总和
    let sumValue = d3.sum(sum, item => item.value);

    // if (sumValue !== 0 && +node.leave === 0) {
    //   // 当前节点不是叶子节点，且自身具有值，那么需要插入一个虚拟叶子节点用来占据空间
    //   result.push(Object.assign({}, { name: '虚拟' + node.name, parent: node.name, level: node.level, leave: "1", industries: sum }))
    // }

    // if (+node.leave !== 0)
    result.push(Object.assign({}, node, { industries: sum }))
    // else
    //   result.push(Object.assign({}, node))
  }




  let hierarchy = this.stratify(result)
  console.log(hierarchy)
  hierarchy.eachAfter(function (node) {
    if (node.id !== '根定向') {
      node.value = d3.sum(node.data.industries, item => item.value)
    } else {
      node.value = d3.sum(node.children, item => item.value)
    }
  });

  // console.log(hierarchy);

  return this.treemap(hierarchy);
}

export default chart;